
from constant import *


class agent(QPushButton):
    def __init__(self,father,type=1):
        super().__init__(father)
        self.wm=father
        self.step=step
        self.dx_step=d_step
        self.dy_step=d_step
        self.ystep=self.step
        self.img_state=['s','d']
        self.type=type
        if self.type==2:
            self.dy_step*=0.72
            self.dy_step=int(self.dy_step)
            self.ystep=int(self.step*0.72)
        self.reset()
        self.init()
        self.show()
        self.setEnabled(False)
        
        self.act_dic={
            0:0,
            1:1,
            16:2,
            2:3,
            4:4,
            8:5,
            18:6,
            20:7,
            10:8,
            12:9,
            17:10,
            3:11,
            5:12,
            9:13,
            19:14,
            21:15,
            11:16,
            13:17
        }

    def reset(self):
        self.act_state=l_state
        self.px=0
        self.py=0
        self.act=0
        self.a=0
        self.w=0
        self.s=0
        self.d=0
        self.j=0
        self.img_index=0
        self.arrived=False
        self.init()

    def init(self):
        if self.type==1:
            self.resize(96,96)
        if self.type==2:
            self.resize(80,80)
        if self.type==1:
            self.move(int((right_x-left_x)/2),bottom)
        else:
            self.move(int((right_x-left_x)/2),up)
    
    def set_image(self,img):
        self.setStyleSheet('border-image:url(:/img/%s.png)'%img)
    
    def submit_action(self,act,x,y):
        
        ns,r= self.wm.submit_act(act,self.x()+self.width()/2,self.y()+self.height()/2,x,y,self.type)
        return ns,r

    def set_action(self):

        # if self.type==2:
        #     self.choose_action()
        #     return 

        act=(self.w*16+self.s*8+self.a*4+self.d*2+self.j)
        self.act=self.act_dic[act] if act in self.act_dic.keys() else 0
    
    def one_step(self,act):
        self.act=act
        ns,r=self.execute_action()
        
        return ns,r
        
    
    def gen_target(self,act):
        x=None
        y=None
        if act==12:
            if self.type==1:
                x,y=ramdom_pt(left_x+50,mid_up-60,left_x+50+150,mid_up-160)
            else:
                x,y=ramdom_pt(left_x+50,mid_down+120,left_x+50+150,mid_down+200)
        if act==15:
            x,y=ramdom_pt(left_x+50,up,left_x+50+90,up+90)
            
        if act==10:
            x,y=ramdom_pt(self.x()-45,up+90,self.x()+45,up)
            
        if act==14:
            x,y=ramdom_pt(right_x-50,up,right_x-50-90,up+90)
            
        if act==11:
            if self.type==1:
                x,y=ramdom_pt(right_x-50,mid_up-60,right_x-50-150,mid_up-160)
            else:
                x,y=ramdom_pt(right_x-50,mid_down+120,right_x-50-150,mid_down+200)
            
        if act==16:
            x,y=ramdom_pt(right_x-50,bottom,right_x-50-90,bottom-90)
            
        if act==13:
            x,y=ramdom_pt(self.x()-45,bottom,self.x()+45,bottom-90)
        if act==17:
            x,y=ramdom_pt(left_x+50,bottom,left_x+50+90,bottom-90)

        if act==1:
            if self.type==1:
                x,y=ramdom_pt(self.x()-45,up+90,self.x()+45,up)
            else:
                x,y=ramdom_pt(self.x()-45,bottom,self.x()+45,bottom-90)
        return x,y

            


    def execute_action(self):
        x=0
        y=0
        ns=None
        r=None
        if self.act in attack_acts:

            if self.type==2:
                if self.act==15 or self.act==10 or self.act==14:
                    self.act=1
            
            if self.type==1:
                if self.act==17 or self.act==13 or self.act==16:
                    self.act=1
            if self.wm.get_game_state()==P1_START and self.type==1:
                if self.act==12:
                    self.act=15
                if self.act==11:
                    self.act=14

            x,y=self.gen_target(self.act)

            

        if self.act==7 or self.act==15:
            self.movd(-self.dx_step,-self.dy_step)
        if self.act==4 or self.act==12:
            self.movd(-self.step,0)
        if self.act==2 or self.act==10:
            self.movd(0,-self.ystep)
        if self.act==9 or self.act==17:
            self.movd(-self.dx_step,self.dy_step)
        if self.act==5 or self.act==13:
            self.movd(0,self.ystep)
        if self.act==8 or self.act==16:
            self.movd( self.dx_step,self.dy_step)
        if self.act==3 or self.act==11:
            self.movd(self.step,0)
        if self.act==6 or self.act==14:
            self.movd(self.dx_step,-self.dy_step)

        ns,r=self.submit_action(self.act,x,y)


        if not self.act==0 :
            self.dynamic_pic()

        return ns,r
    
    def dynamic_pic(self):
        self.img_index+=1
        self.img_index%=2
        direct='l'
        if self.act in l_actions:
            direct='l'
        elif self.act in r_actions:
            direct='r'

        self.set_image('a%d%s%s'%(self.type,self.img_state[self.img_index],direct))



    def movd(self,dx,dy):
        x=self.x()+dx
        if x<left_x:
            x=left_x
        if x>right_x:
            x=right_x
        y=self.y()+dy

        if y>bottom:
            y=bottom
        if y<up:
            y=up
        
        if self.type==1 and y<mid_down:
            y=mid_down

        if self.type==2 and y>mid_up:
            y=mid_up

        if self.type==2 and self.wm.get_game_state()==P1_START:
            y =y if y<=up+20 else up+20
            x=x if x>(left_x+right_x)/2-30 else int((left_x+right_x)/2-30)
            x=x if x<(left_x+right_x)/2+30 else int((left_x+right_x)/2+30)

        if self.type==1 and self.wm.get_game_state()==P2_START:
            y =y if y>=bottom-20 else bottom-20
            x=x if x>(left_x+right_x)/2-30 else int((left_x+right_x)/2-30)
            x=x if x<(left_x+right_x)/2+30 else int((left_x+right_x)/2+30)
        
        if self.type==1 and self.wm.get_game_state()==P1_START:
            y =y if y>=bottom-20 else bottom-20
            x=x if x>(left_x+right_x)/2-30 else int((left_x+right_x)/2-30)
            x=x if x<(left_x+right_x)/2+30 else int((left_x+right_x)/2+30)

        self.move(x,y)
        self.px=self.x()
        self.py=self.y()
        

    def mov(self,x,y):
        if x<left_x:
            x=left_x
        if x>right_x:
            x=right_x
        if y>bottom:
            y=bottom
        if y<up:
            y=up
        if self.type==1 and y<mid_down:
            y=mid_down

        if self.type==2 and y>mid_up:
            y=mid_up
        self.move(x,y)
        self.px=self.x()
        self.py=self.y()

    
    def mov2pos(self,x,y):
        
        theta=0.0
        try:
            if math.sqrt(math.pow((self.x()-x),2)+math.pow((self.y()-y),2))<step:
                self.act=0
                return


            if self.px>=x:
                if self.py>=y:
                    theta=math.atan(float(self.py-y)/(self.px-x))
                    theta=math.degrees(theta)
                    
                    if abs(theta-45)<22.5:
                        self.act=7
                    elif theta<45:
                        self.act=4
                    else:
                        self.act=2
                else:
                    theta=math.atan(float(y-self.py)/(self.px-x))
                    theta=math.degrees(theta)
                    if abs(theta-45)<22.5:
                        self.act=9
                    elif theta<45:
                        self.act=4
                    else:
                        self.act=5
            
            else:
                if self.py>=y:
                    theta=math.atan(float(self.py-y)/(x-self.px))
                    theta=math.degrees(theta)
                    if abs(theta-45)<22.5:
                        self.act=6
                    elif theta<45:
                        self.act=3
                    else:
                        self.act=2
                else:
                    theta=math.atan(float(y-self.py)/(x-self.px))
                    theta=math.degrees(theta)
                    if abs(theta-45)<22.5:
                        self.act=8
                    elif theta<45:
                        self.act=3
                    else:
                        self.act=5
        except:
            self.act=0
        # print(self.act)
        
                
            

    def choose_action(self):

        game_state=self.wm.get_game_state()
        
        if game_state==P2_START:
        #    print('?????????????')
           self.act=random.choice(up_start_actcs)

        if game_state==PLAY_2_ON:
            nx=random.randint(0,int(NOISE*2/7))-int(NOISE/7)
            ny=random.randint(0,int(NOISE*2/7))-int(NOISE/7)
            if self.type==1:
                self.mov2pos(DOWNMID[0]+nx,DOWNMID[1]+ny)

        if game_state==PLAY_1_ON:
            
            nx=random.randint(0,int(NOISE*2/7))-int(NOISE/7)
            ny=random.randint(0,int(NOISE*2/7))-int(NOISE/7)
            if self.type==2:
                self.mov2pos(UPMID[0]+nx,UPMID[1]+ny)
            
            
            
        else:
            if self.wm.is_ball_hitable(self.x()+self.width()/2,self.y()+self.height()/2):
                
                self.act=random.choice(attack_acts)

            else:
                x,y=self.wm.get_ball_target()
                bx,by=self.wm.get_ball_pos()
                dis=get_dis(self.x(),self.y(),bx,by)
                nx=NOISE
                if dis<WEAK_RANGE:
                    nx*=math.exp((dis-WEAK_RANGE))
                
                nx=nx if nx>=30 else 30
                nx=int(nx)
                x+=(random.randrange(29,nx)-int(nx/2))
                y+=(random.randrange(29,nx)-int(nx/2))
                self.mov2pos(x,y)

            
    def set_w(self,x):
        self.w=x

    def set_a(self,x):
        self.a=x
    def set_s(self,x):
        self.s=x
    def set_d(self,x):
        self.d=x
    def set_j(self,x):
        self.j=x




class human_agent(agent):
    def __init__(self,father,type=1):
        super().__init__(father,type=type)
        
        self.set_image('a%dsl'%self.type)
        
        
        
